Claude Code 攻略 2.2 - 使用 Claude Code 的 Plan Mode 让事情事半功倍

2025-12-16 | 73分钟 | yrobot | Claude Code,Plan Mode,工作流程,使用方法,最佳实践,任务管理,Subagent

Plan Mode 的困惑与价值

我频繁使用 Claude Code 来处理日常开发任务,很快发现了一个困惑的现象:

有时候,我说"帮我实现用户认证功能",Claude Code 会先进入一个"Plan Mode",探索代码结构、生成实现方案,等我确认后才开始执行。但有时候,同样的需求描述,它却直接开始写代码,但是结果质量不尽如人意,浪费了不少 Token 和时间。

这种不一致性让我开始思考:Claude Code 到底是如何决定什么时候该先规划、什么时候直接执行的?我能不能主动控制这个流程?

经过一段时间的摸索和实践,我逐渐理解了 Claude Code 的工作流程决策机制,也找到了一些引导它的有效方法。

Claude Code 的决策流程:何时规划 vs 直接执行

决策逻辑:任务复杂度评估

Claude Code 在接到任务时,会进行快速的复杂度评估,决定是 直接执行 还是进入 Plan Mode:

用户需求
   ↓
任务复杂度评估
   - 是否涉及多个文件?
   - 是否需要多步骤操作?
   - 是否有多种实现方案?
   - 是否可能影响现有功能?
   ↓
简单任务 → 直接执行
复杂任务 → 进入 Plan Mode

场景分类与判断标准

直接执行的场景

  • 微调整:修改文案、添加依赖、删除文件
  • 单一操作:单个函数修改、配置文件调整

容易产生歧义的场景

  • 中等复杂度任务:添加功能(可能涉及多文件)、修复 Bug、小范围重构
  • 建议:明确要求先规划,避免方向错误

建议规划的场景

  • 复杂任务:认证系统、架构重构、数据迁移、性能优化
  • 多文件协调:涉及 3 个以上文件修改
  • 数据相关:数据库迁移、API 接口变更

为什么会出现"应该规划却直接执行"?

主要原因是系统默认倾向于直接执行(体现效率)、对复杂任务的判断可能不够准确、以及用户描述模糊导致被误解。解决方法是在复杂任务时明确要求先规划。

为什么需要 Plan Mode:从上下文工程看规划的必要性

在前面我们讨论了"何时规划 vs 直接执行"的决策逻辑,但还有一个更深层的问题:为什么 Claude Code 要专门设计一个独立的 Plan Mode?

问题 1:上下文漂移导致的规划失效

在一次对话中,随着交互的进行,LLM 的注意力焦点会不断变化。这种变化如果不加控制,就会导致早期的规划被逐渐"遗忘"。

在直接执行模式下,随着实现的深入,注意力会从原始需求逐渐转移到代码错误、依赖问题、测试调试等细节上。原始规划中的"还需要更新文档"等后续步骤容易被遗漏。

Plan Mode 通过文件持久化和上下文隔离解决这个问题:

  • 规划阶段:专注于规划,生成完整的实现步骤并保存为 plan.md 文件
  • 执行阶段:plan.md 内容始终在上下文顶部,即使注意力在调试,规划仍清晰可见

核心差异:Plan Mode 确保规划不会被实现细节淹没。

问题 2:方向错误的成本累积

在规划阶段发现方向问题的成本,远低于执行后返工的成本。

没有 Plan Mode 的风险:可能写了几十行代码后,才发现方向不对(比如数据库 schema 还没更新、现有系统需要保留等),导致返工。

有 Plan Mode 的优势:Explore Agent 在规划阶段就能发现潜在问题,用户可以提前审查和调整方案,避免浪费时间和 Token。

问题 3:复杂依赖的心智负担

复杂任务往往涉及多个步骤和依赖关系。人类和 LLM 都有工作记忆限制,难以同时记住所有依赖细节。

Plan Mode 的解决方案:

  1. 在规划阶段识别所有依赖关系
  2. 按依赖顺序排列步骤
  3. 明确标注每步的前置条件和输出

执行阶段只需关注当前步骤,plan 文件清晰记录了依赖关系,无需记忆所有细节。

核心优势:将依赖关系外化为文档,降低心智负担。

为什么需要独立的 Plan Mode

Plan Mode 通过独立的规划阶段和文件持久化,从三个层面解决上下文管理问题:规划专注于"做什么"而 plan 文件始终保持在执行时的上下文顶部(上下文隔离)、在规划阶段就能发现方向问题避免返工(降低试错成本)、将依赖关系显式化为文档(管理复杂度)。

这是上下文架构层面的设计,而不仅仅是"规划 vs 不规划"的区别。

Plan Mode 的完整工作流程:五个阶段的深度解析

当 Claude Code 决定进入 Plan Mode 后,会执行一套完整的工作流程,确保方案的合理性和可行性。

Phase 1:初始理解(Initial Understanding)

目标:理解需求 + 探索代码库结构

核心机制

  • 最多启动 3 个 Explore Agent 并行探索
  • 每个 Agent 负责不同的探索方向
  • 只探索相关内容,避免读取整个代码库

Explore Agent 通过 Glob 查找文件模式、Grep 搜索关键词、Read 读取关键文件的方式,高效探索代码库,最后输出包含代码结构理解、相关文件清单和技术栈分析的报告。

Phase 2:设计(Design)

目标:基于探索结果,设计实现方案

核心机制

  • 启动 1 个 Plan Agent
  • 基于探索结果进行方案设计
  • 考虑依赖关系和实现顺序

Plan Agent 会输出包含技术选择、实现步骤、文件清单的设计方案,为后续实现提供明确的指导。

Phase 3:审查(Review)

目标:确保方案合理,发现潜在问题

核心机制

  • 读取关键文件验证假设
  • 与用户确认有歧义的部分
  • 使用 AskUserQuestion 获取决策

审查的四个维度

  1. 逻辑正确性:检查步骤依赖是否成立、前置假设是否验证
  2. 技术可行性:检查技术栈兼容性、现有代码兼容性
  3. 安全性评估:检查常见安全风险(SQL 注入、XSS、权限漏洞、密码安全等)
  4. 资源约束:评估 Token 成本、执行时间、性能影响

具体审查内容

逻辑正确性审查:步骤 B 依赖步骤 A 的输出时,确认 A 确实会产生 B 需要的结果;涉及数据库操作时,验证 schema 是否已存在;使用第三方库时,确认项目中已安装。

技术可行性审查:新功能使用的技术栈要与项目现有技术一致(如项目用 TypeScript 不要建议写 JavaScript);API 调用方式要符合现有代码风格(如项目用 axios 不要突然用 fetch);框架版本要兼容(读取 package.json 确认版本)。

安全性审查:用户输入是否经过验证和清理、密码是否正确加密存储(bcrypt、不要明文)、API 是否有适当的权限验证、SQL 查询是否使用参数化避免注入、敏感信息是否避免暴露在日志或响应中。

资源约束评估:预估单个步骤需要的上下文 token 数(避免超过 10K)、执行时间评估(单步应 < 5 分钟)、性能影响评估(大量数据操作、循环查询等需要注意)。

假设验证策略

不是所有假设都需要验证,关键是识别出哪些假设如果错误会导致整个方案失败。

  • 高优先级验证:影响后续所有步骤的假设(如数据模型定义、技术栈依赖等)必须读取文件确认
  • 低优先级验证:标准技术实现和通用代码模式可以基于经验推断,执行时再调整

用户交互时机

发现多种实现方案时询问用户偏好、发现技术约束时询问是否需要调整方案、需要业务决策时获取具体参数和配置、发现破坏性变更时确认是否继续。提问时要说明发现的问题或背景、提供的选项以及每个选项的影响。

Phase 4:最终计划(Final Plan)

目标:生成可执行的计划文档

输出位置.claude/plans/xxx.md

计划编写的三个核心原则

  1. 可执行性:每个步骤要足够具体,明确文件路径和操作内容
  2. 可验证性:每个步骤完成后,能够通过明确的标准验证是否成功
  3. 详细程度适中:不要过于详细(失去灵活性),也不要过于简略(难以执行)

步骤颗粒度的判断标准

单一职责原则(一个步骤只做一件事)、可独立验证(步骤完成后能单独验证结果)、执行时间控制(每个步骤执行时间应 < 5 分钟)、Token 成本控制(每个步骤需要的上下文应 < 10K tokens)。

计划应包含概述、技术选择、实现步骤(文件、操作、验收标准、依赖关系)和待确认问题。

对比示例:添加用户认证功能

糟糕的计划(过于简略,难以执行):

1. 创建 User 模型
2. 实现登录功能
3. 添加权限验证
4. 更新前端页面

好的计划(可执行、可验证):

## 步骤 1:创建 User 数据模型

- 文件:`src/models/User.ts`
- 操作:定义 User 接口,包含 id、email、passwordHash、role 字段
- 验证:TypeScript 编译通过,类型定义完整

## 步骤 2:实现用户注册 API

- 文件:`src/api/auth/register.ts`
- 操作:创建 POST /api/auth/register 端点,接收 email 和 password,使用 bcrypt 加密密码后存入数据库
- 依赖:步骤 1 完成
- 验证:使用 Postman 测试注册成功,数据库中密码已加密

## 步骤 3:实现用户登录 API

- 文件:`src/api/auth/login.ts`
- 操作:创建 POST /api/auth/login 端点,验证密码后生成 JWT token(有效期 7 天)
- 依赖:步骤 2 完成
- 验证:登录成功返回 token,错误密码返回 401

## 步骤 4:实现权限验证中间件

- 文件:`src/middleware/auth.ts`
- 操作:创建 requireAuth 中间件,验证 JWT token 并将 user 信息注入 req.user
- 依赖:步骤 3 完成
- 验证:未授权访问返回 401,有效 token 通过验证

关键差异:好的计划明确了文件路径、具体操作内容、验证标准和依赖关系,执行时不需要额外思考"该怎么做"。

Phase 5:退出 Plan Mode

工具:ExitPlanMode

等待用户确认:是否执行计划

退出后的执行机制

退出 Plan Mode 后,Claude Code 有一套完整的执行流程:

  1. 读取 plan.md 文件,加载到上下文顶部
  2. 确认执行范围(全部/部分/分阶段)
  3. 逐步执行:当前步骤 → 完成 → 验证 → 下一步
  4. plan.md 始终在上下文中,不会被实现细节淹没

关键特点:逐步提取信息、自动进度追踪、持续与 plan 交互。

执行过程中的调整策略

轻微调整(如文件路径调整):在对话中说明,继续执行,计划保持不变。

中等调整(如需要新增步骤):暂停当前步骤,说明原因,询问用户是否调整计划或继续执行。

重大调整(如前置假设不成立):立即停止,说明问题和影响,建议重新进入 Plan Mode。

执行失败的处理

轻微失败(语法错误、类型错误):自动修复,继续执行。

中等失败(逻辑错误、测试失败):分析原因,询问用户(修复后继续/跳过/暂停)。

严重失败(方向错误、假设不成立):停止执行,建议重新规划,等待用户决策。

验证机制

  • 自动验证:语法检查、基础功能验证(不需要用户介入)
  • 半自动验证:测试运行、集成验证(可能需要用户确认)
  • 手动验证:功能测试、UI 验证、性能测试(需要用户操作)

执行完成后的总结:包含完成步骤数、文件变更、测试结果、验证建议和优化建议。

Explore Agent 的高效探索机制

为什么需要 Explore Agent?

传统做法(Read 所有文件)会消耗大量 Token 并导致信息过载。Explore Agent 通过 Glob 查找文件模式、Grep 搜索关键词、Read 关键部分的方式,实现精确定位和智能筛选。

探索策略

  • 关键词扩展:从核心词扩展到相关词(如:payment → billing, checkout, transaction)
  • 文件名模式:直接模式(payment_)+ 间接模式(_order, _subscription_)
  • 代码搜索优先级:类型定义 → 服务层 → API 层 → 配置文件

工作示例:探索支付功能

用户需求:"添加支付功能"

Explore Agent 的探索过程:

第 1 步:文件名探索
- Glob: **/*payment* → 找到 PaymentService.ts
- Glob: **/*billing* → 找到 BillingController.ts
- Glob: **/*order* → 找到 Order.ts, OrderService.ts

第 2 步:代码关键词搜索
- Grep: "payment" → 在 Order.ts 中发现 paymentStatus 字段
- Grep: "stripe|paypal" → 未找到,说明尚未集成支付服务
- Grep: "interface.*Payment" → 找到 PaymentMethod 接口定义

第 3 步:读取关键文件
- Read: Order.ts → 了解订单数据结构,发现 totalAmount 字段
- Read: PaymentMethod 接口 → 了解现有支付方式定义
- Read: package.json → 确认项目使用 TypeScript + Express

输出报告:
- 代码结构:订单系统已存在,有 paymentStatus 字段但未实现具体支付逻辑
- 相关文件:Order.ts, OrderService.ts, PaymentMethod 接口
- 技术栈:TypeScript + Express,尚未集成第三方支付 SDK
- 建议:需要选择支付服务提供商(Stripe/PayPal),实现支付 API 端点

这个探索过程只读取了 3-4 个关键文件,就完整了解了现有代码结构和需要补充的内容。

Plan Agent 的任务拆解逻辑

拆解原则

  1. 单一职责:每个步骤只做一件事
  2. 依赖顺序:按照依赖关系排序,确保执行顺序合理
  3. 可测试性:每个步骤都可以独立验证和测试

Plan Agent 会将需求拆解为核心功能,细化每个功能的实现步骤,最后按依赖顺序排列执行顺序。

正确的使用姿势和最佳实践

任务分类与引导策略

任务类型 规划需求 引导方式 示例
微调整 不需要 直接描述 "把标题改得更吸引人"
单一操作 不需要 明确指令 "删除这个未使用的文件"
小功能 建议 明确要求规划 "先规划,帮我添加搜索功能"
中等功能 必须 强制规划 "进入 Plan Mode,设计用户系统"
大功能 必须 分阶段规划 "第一阶段:先设计认证方案"

主动触发 Plan Mode 的方法

方法 1:显式要求规划

对于稍微复杂的任务,明确要求先规划:"先进入 Plan Mode,帮我设计用户认证的实现方案"

方法 2:强调探索和理解

强调"先探索":"先了解现有代码架构,然后给我一个用户认证功能的实现方案"

方法 3:提出问题引导思考

用提问方式引导:"我想添加用户认证,你觉得有哪些实现方式?各有什么优缺点?"

实际应用示例

场景:为现有项目添加搜索功能

❌ 不好的做法(直接要求实现):

用户:"帮我添加搜索功能"
Claude Code:直接开始写代码 → 不了解现有架构 → 方向可能错误

✓ 好的做法(主动引导规划):

用户:"先进入 Plan Mode,帮我设计搜索功能。项目使用 Next.js + PostgreSQL,
      需要支持按标题和内容搜索。"

Claude Code:
1. 启动 Explore Agent,探索现有数据模型和 API 结构
2. 发现项目用 Prisma ORM,推荐使用全文搜索
3. 设计方案:
   - 步骤 1:更新 Prisma schema,添加全文搜索索引
   - 步骤 2:创建搜索 API 端点 /api/search
   - 步骤 3:实现前端搜索组件
4. 询问用户:是否需要实时搜索(输入时自动搜索)还是点击按钮搜索?
5. 生成最终计划,等待确认

关键差异:提供足够上下文(技术栈、需求细节),明确要求规划,让 AI 有足够信息做出正确设计。

常见问题的解决策略

AI 直接执行但方向错误:要求"停止执行,先进入 Plan Mode";预防措施是使用"设计"、"方案"、"规划"等关键词。

规划过于详细:建议分阶段执行,每个阶段包含 3-5 个步骤。

探索不够全面:提供相关线索("项目使用了 TypeORM 和 Redis")或要求多角度探索。

完整工作流程图

graph TD
    A[用户提出需求] --> B{任务复杂度评估}

    B -->|简单任务| C[直接执行]
    B -->|复杂任务| D[进入 Plan Mode]

    D --> E[Phase 1: 初始理解]
    E --> F[Explore Agent 探索]
    F --> G[生成探索报告]

    G --> H[Phase 2: 设计方案]
    H --> I[Plan Agent 设计]
    I --> J[生成初步方案]

    J --> K[Phase 3: 审查]
    K --> L{需要用户确认?}
    L -->|是| M[AskUserQuestion]
    L -->|否| N[Phase 4: 最终计划]
    M --> O[获取用户反馈]
    O --> N

    N --> P[写入计划文件]
    P --> Q[Phase 5: 退出 Plan Mode]

    Q --> R{用户确认执行?}
    R -->|确认| S[按计划执行]
    R -->|调整| T[修改计划]
    R -->|取消| U[任务结束]

    T --> S
    C --> V[任务完成]
    S --> V

一些实践心得

关于决策机制

Claude Code 的任务判断更像是基于启发式规则,而非精确算法。同样的任务描述,在不同上下文下可能有不同处理方式。与其依赖自动判断,不如主动说明期望的工作方式。需要规划就明确说"先规划",简单任务直接说"直接实现"。

关于 Plan Mode 的价值

最初觉得 Plan Mode 繁琐,但经历几次"写到一半发现方向错了"后,开始理解规划的价值。复杂任务时,Plan Mode 能帮助 AI 理清思路,也让我提前发现潜在问题。现在的习惯是:不确定就先规划。

关于引导技巧

引导需要平衡:过度详细让 AI 失去自主性,过于模糊又容易偏离方向。我的做法是提供清晰的目标和约束条件,具体实现交给 AI。比如"实现用户认证,使用 JWT,需要支持角色权限",而不是逐步指令。

思维方式的转变

从"逐步指导"到"委托任务"需要时间适应。学会放手让 AI 自己规划和执行,不仅提升了效率,也让我有更多精力思考架构和设计层面的问题。